home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / os2 / ext2_200.zip / EXT2_SRC.ZIP / 32BITS / EXT2-OS2 / EXT2FLT / E2ROUTER.C < prev    next >
C/C++ Source or Header  |  1996-01-24  |  8KB  |  199 lines

  1. /************************************************************************/
  2. /*                       Linux partition filter.                        */
  3. /*          (C) Copyright Deon van der Westhuysen, July 1995.           */
  4. /*                                                                      */
  5. /*  Dedicated to Jesus Christ, my Lord and Saviour.                     */
  6. /*                                                                      */
  7. /* This program is free software; you can redistribute it and/or modify */
  8. /* it under the terms of the GNU General Public License as published by */
  9. /* the Free Software Foundation; either version 2, or (at your option)  */
  10. /* any later version.                                                   */
  11. /*                                                                      */
  12. /* This program is distributed in the hope that it will be useful,      */
  13. /* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
  14. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
  15. /* GNU General Public License for more details.                         */
  16. /*                                                                      */
  17. /* You should have received a copy of the GNU General Public License    */
  18. /* along with this program; if not, write to the Free Software          */
  19. /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            */
  20. /*                                                                      */
  21. /*  This code is still under development; expect some rough edges.      */
  22. /*                                                                      */
  23. /************************************************************************/
  24.  
  25. #include "debug.h"
  26. #include "e2data.h"
  27. #include "e2router.h"
  28. #include "e2wrap.h"
  29. #include "e2filt.h"
  30. #include "e2part.h"
  31.  
  32. /* Macro to test whether an pointer points to an element in the array */
  33. #define IS_ELEMENT(PTR,ARRAY,SIZE)    ((((VOID*)PTR)>=((VOID*)ARRAY))&&\
  34.                      (((VOID*)PTR)<((VOID*)(ARRAY+SIZE))))
  35.  
  36. /* All IORBs arrive here. We queue the IORB and then call the queue server */
  37. /* to take over. */
  38. void E2FilterIORB (PIORB pIORB)
  39. {
  40.  NPRecHeader    pUnitRec;            /* Ptr to unit rec for IORB */
  41.  NPIORBQueue    pQueue;                /* Ptr to queue for IORB */
  42.  
  43.  if (pIORB->CommandCode==IOCC_CONFIGURATION)    /* For configuration IORBs: */
  44.   pUnitRec= (NPRecHeader) VirtUnits;        /* Assign IORB to the first */
  45.                         /* virtual unit. (For queue) */
  46.  else
  47.   pUnitRec= (NPRecHeader) pIORB->UnitHandle;    /* Get pointer to unit */
  48.                         /* from the unit handle */
  49.  /* Check to see if pUnitRec is a pointer to a valid unit record. */
  50.  if (!(IS_ELEMENT(pUnitRec,BaseUnits,NumBaseUnits)||
  51.        IS_ELEMENT(pUnitRec,VirtUnits,NumVirtUnits)))
  52.  {
  53.   IORBError (pIORB,IOERR_NO_SUCH_UNIT);        /* Tell them they are crazy! */
  54.   NotifyDone (pIORB);                /* Notify that we are done */
  55.  }
  56.  else
  57.  {
  58.   pQueue= &(pUnitRec->IORBQueue);        /* Get pointer to IORB queue */
  59.   DISABLE                    /* Same safety... */
  60.   AddIORBToQueue (pQueue,pIORB);        /* Add IORB to queue */
  61.   ENABLE                    /* Re-enable interrupts */
  62.   StartIORBQueue (pQueue);            /* Try to restart the queue */
  63.  }
  64. }
  65.  
  66. /* Function to add an IORB to a queue of IORBs maintainded for the unit. */
  67. /* MUST be called with interrupts disabled. */
  68. void AddIORBToQueue (NPIORBQueue pQueue, PIORB pIORB)
  69. {
  70.  if (pQueue->pTail)                /* Queue had IORBs waiting: */
  71.   pQueue->pTail->pNxtIORB= pIORB;        /* Add IORB into queue */
  72.  else                        /* Queue was empty: */
  73.   pQueue->pHead= pIORB;                /* Add IORB into queue */
  74.  while (pIORB->RequestControl&IORB_CHAIN)    /* If not last IORB in chain */
  75.   pIORB= pIORB->pNxtIORB;            /* Seek next IORB in request */
  76.  (pQueue->pTail= pIORB)->pNxtIORB= 0;        /* Set new tail pointer and */
  77.                         /* clear ptr to chained IORB */
  78. }
  79.  
  80. /* Function retrieve an IORB from the queue. Returns NULL if the queue was */
  81. /* empty. MUST be called with interrupts disabled. */
  82. PIORB GetIORBFromQueue (NPIORBQueue pQueue)
  83. {
  84.  PIORB    pReturnIORB;                /* Pointer to return */
  85.  
  86.  if (pQueue->pHead)                /* If queue is not empty: */
  87.  {
  88.   pReturnIORB= pQueue->pHead;            /* Get pointer to head */
  89.   pQueue->pHead= pReturnIORB->pNxtIORB;        /* Update the head pointer */
  90.   if (!pQueue->pHead)                /* If queue now is empty: */
  91.    pQueue->pTail= NULL;                /* Clear the tail pointer */
  92.  }
  93.  else
  94.   pReturnIORB= NULL;                /* Queue empty: return NULL */
  95.  return pReturnIORB;
  96. }
  97.  
  98. /* Function to service an IORB queue. It first checks that the queue is not */
  99. /* being serviced before entering the service loop. */
  100. void StartIORBQueue (NPIORBQueue pQueue)
  101. {
  102.  PIORB            pIORB;            /* Ptr to IORB to execute */
  103.  NPRecHeader        pUnitRec;        /* Pointer to unit record */
  104.  
  105.  DISABLE                    
  106.  if (!(pQueue->Flags&F_SERVER_ACTIVE))        /* Check to no one is busy */
  107.                         /* servicing this queue */
  108.  {
  109.   pQueue->Flags|=F_SERVER_ACTIVE;        /* Grap control of queue */
  110.   /* If we get where we have exclusize access to the queue. */
  111.   while ((!(pQueue->Flags&F_REQUEST_BUSY))&&
  112.          ((pIORB= GetIORBFromQueue (pQueue))!=NULL))
  113.                         /* Loop while there is an */
  114.                         /* IORB ready to be serviced */
  115.                         /* and the previous IORB is */
  116.                         /* finished. */
  117.   {
  118.    pQueue->Flags|=F_REQUEST_BUSY;        /* Show request in progress */
  119.    ENABLE
  120.  
  121.    if (pIORB->CommandCode==IOCC_CONFIGURATION)    /* For configuration IORBs: */
  122.     pUnitRec= (NPRecHeader) VirtUnits;        /* Assign IORB to the first */
  123.                         /* virtual unit. (For queue) */
  124.    else
  125.     pUnitRec= (NPRecHeader) pIORB->UnitHandle;    /* Get pointer to unit */
  126.                         /* from the unit handle */
  127.  
  128.    /* We will handle (de)allocation and allocation checks here since it is */
  129.    /* common between the two parts- filter and virtual units. */
  130.    if (pIORB->CommandCode==IOCC_UNIT_CONTROL)    /* Unit control command? */
  131.    {
  132.     if (pIORB->CommandModifier==IOCM_ALLOCATE_UNIT)
  133.     {                        /* Allocate unit??? */
  134.      if (pUnitRec->Flags&F_ALLOCATED)        
  135.       IORBError (pIORB,IOERR_UNIT_ALLOCATED);    /* Error if allocated */
  136.      else
  137.       pUnitRec->Flags|=F_ALLOCATED;        /* Else allocate the unit */
  138.      pQueue->Flags&=~F_REQUEST_BUSY;        /* Indicate queue finished */
  139.      NotifyDone (pIORB);
  140.      continue;                    /* Service next request */
  141.     }
  142.     if (pIORB->CommandModifier==IOCM_DEALLOCATE_UNIT)
  143.     {                        /* Deallocate unit??? */
  144.      if (!(pUnitRec->Flags&F_ALLOCATED))    
  145.       IORBError (pIORB,IOERR_UNIT_NOT_ALLOCATED);
  146.                         /* Error if not allocated */
  147.      else
  148.       pUnitRec->Flags&=~F_ALLOCATED;        /* Else deallocate unit */
  149.      pQueue->Flags&=~F_REQUEST_BUSY;        /* Indicate queue finished */
  150.      NotifyDone (pIORB);
  151.      continue;                    /* Service next request */
  152.     }
  153.    }
  154.  
  155.    /* Do allocations checks... if notify points to us, skip check. */
  156.    if (!(pUnitRec->Flags&F_ALLOCATED))        /* If unit is not allocated: */
  157.     if (pIORB->NotifyAddress!=&PartNotifyWrapper)
  158.                         /* and we didn't make request */
  159.      if (pIORB->CommandCode!=IOCC_CONFIGURATION)
  160.                         /*  and not configuration */
  161.      {
  162.       IORBError (pIORB,IOERR_UNIT_NOT_ALLOCATED);
  163.                         /* Then it is an error */
  164.       pQueue->Flags&=~F_REQUEST_BUSY;        /* Indicate queue finished */
  165.       NotifyDone (pIORB);
  166.       continue;                    /* Service next request */
  167.      }
  168.  
  169.  
  170.    if (IS_ELEMENT(pUnitRec,BaseUnits,NumBaseUnits)) 
  171.     FilterHandler (pIORB);            /* Handler for base units */
  172.    else if (IS_ELEMENT(pUnitRec,VirtUnits,NumVirtUnits))
  173.     PartHandler (pIORB);            /* Handler for virtual units */
  174.    DISABLE
  175.   }
  176.   /* Tell others that this server is not active any more... */
  177.   pQueue->Flags&=~F_SERVER_ACTIVE;
  178.  }
  179.  ENABLE
  180. }
  181.  
  182. /* Notify client that the IORB processing is completed. */
  183. void NotifyDone (PIORB pIORB)
  184. {
  185.  pIORB->Status |= IORB_DONE;            /* Set 'DONE' flag */
  186.  if (pIORB->RequestControl&IORB_ASYNC_POST)    /* If notify flag set... */
  187.   pIORB->NotifyAddress(pIORB);            /* Notify the caller */
  188. }
  189.  
  190. /* Function to return an error code via IORB */
  191. void IORBError (PIORB pIORB, USHORT ErrorCode)
  192. {
  193.  if (ErrorCode)                    /* If really an error: */
  194.  {
  195.   pIORB->Status |= IORB_ERROR;            /* Set error flag */
  196.   pIORB->ErrorCode= ErrorCode;            /* Fill in error code field */
  197.  }
  198. }
  199.